package org.jeecg.modules.business.rlzy.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ZipUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.system.base.controller.JeecgController;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.util.DateUtils;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.business.excelUtils.ExcelExportServer;
import org.jeecg.modules.business.excelUtils.JeecgEntityExcelView;
import org.jeecg.modules.business.rlzy.entity.BuGsfwptRlzy;
import org.jeecg.modules.business.rlzy.service.IBuGsfwptRlzyService;
import org.jeecg.modules.business.rlzy.vo.DictVo;
import org.jeecg.modules.business.rlzy.vo.QyNumVo;
import org.jeecg.modules.business.rlzy.vo.TotalParamVo;
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
import org.jeecgframework.poi.excel.entity.ExportParams;
import org.jeecgframework.poi.excel.entity.enmus.ExcelType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.*;
import java.util.stream.Collectors;

/**
 * @Description: 人力资源完税
 * @Author: jeecg-boot
 * @Date:   2023-04-03
 * @Version: V1.0
 */
@Api(tags="人力资源完税")
@RestController
@RequestMapping("/rlzy/buGsfwptRlzy")
@Slf4j
public class BuGsfwptRlzyController extends JeecgController<BuGsfwptRlzy, IBuGsfwptRlzyService> {
	@Autowired
	private IBuGsfwptRlzyService buGsfwptRlzyService;
	@Value("${jeecg.path.upload}")
	private String upLoadPath;

	@Autowired
	private RedisUtil redisUtil;
	private ExecutorService executorService = new ThreadPoolExecutor(10, 50, 0L,TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());

	/**
	 * 分页列表查询
	 *
	 * @param buGsfwptRlzy
	 * @param pageNo
	 * @param pageSize
	 * @param req
	 * @return
	 */
	@AutoLog(value = "人力资源完税-分页列表查询")
	@ApiOperation(value="人力资源完税-分页列表查询", notes="人力资源完税-分页列表查询")
	@GetMapping(value = "/list")
	public Result<?> queryPageList(BuGsfwptRlzy buGsfwptRlzy,
								   @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
								   @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
								   HttpServletRequest req) {
		QueryWrapper<BuGsfwptRlzy> queryWrapper = QueryGenerator.initQueryWrapper(buGsfwptRlzy, req.getParameterMap());
		Page<BuGsfwptRlzy> page = new Page<BuGsfwptRlzy>(pageNo, pageSize);
		IPage<BuGsfwptRlzy> pageList = buGsfwptRlzyService.page(page, queryWrapper);
		return Result.OK(pageList);
	}
	 /**
	  * 自定义分页列表查询
	  *
	  * @param buGsfwptRlzy
	  * @param pageNo
	  * @param pageSize
	  * @param req
	  * @return
	  */
	 @AutoLog(value = "人力资源完税-自定义分页列表查询")
	 @ApiOperation(value="人力资源完税-自定义分页列表查询", notes="人力资源完税-自定义分页列表查询")
	 @GetMapping(value = "/customRlzyList")
	 public Result<?> queryRlzyPageListByCustom(BuGsfwptRlzy buGsfwptRlzy,
									@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
									@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
									HttpServletRequest req) {
		 Page<BuGsfwptRlzy> page = new Page<BuGsfwptRlzy>(pageNo, pageSize);
		 IPage<BuGsfwptRlzy> pageList = buGsfwptRlzyService.queryRlzyPageListByCustom(page, buGsfwptRlzy);
		 return Result.OK(pageList);
	 }
	/**
	 *   添加
	 *
	 * @param buGsfwptRlzy
	 * @return
	 */
	@AutoLog(value = "人力资源完税-添加")
	@ApiOperation(value="人力资源完税-添加", notes="人力资源完税-添加")
	@PostMapping(value = "/add")
	public Result<?> add(@RequestBody BuGsfwptRlzy buGsfwptRlzy) {
		buGsfwptRlzyService.save(buGsfwptRlzy);
		return Result.OK("添加成功！");
	}

	/**
	 *  编辑
	 *
	 * @param buGsfwptRlzy
	 * @return
	 */
	@AutoLog(value = "人力资源完税-编辑")
	@ApiOperation(value="人力资源完税-编辑", notes="人力资源完税-编辑")
	@PutMapping(value = "/edit")
	public Result<?> edit(@RequestBody BuGsfwptRlzy buGsfwptRlzy) {
		buGsfwptRlzyService.updateById(buGsfwptRlzy);
		return Result.OK("编辑成功!");
	}

	/**
	 *   通过id删除
	 *
	 * @param id
	 * @return
	 */
	@AutoLog(value = "人力资源完税-通过id删除")
	@ApiOperation(value="人力资源完税-通过id删除", notes="人力资源完税-通过id删除")
	@RequestMapping(value = "/delete")
	public Result<?> delete(@RequestParam(name="id",required=true) String id) {
		buGsfwptRlzyService.removeById(id);
		return Result.OK("删除成功!");
	}

	/**
	 *  批量删除
	 *
	 * @param ids
	 * @return
	 */
	@AutoLog(value = "人力资源完税-批量删除")
	@ApiOperation(value="人力资源完税-批量删除", notes="人力资源完税-批量删除")
	@RequestMapping(value = "/deleteBatch")
	public Result<?> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
		this.buGsfwptRlzyService.removeByIds(Arrays.asList(ids.split(",")));
		return Result.OK("批量删除成功!");
	}

	/**
	 * 通过id查询
	 *
	 * @param id
	 * @return
	 */
	@AutoLog(value = "人力资源完税-通过id查询")
	@ApiOperation(value="人力资源完税-通过id查询", notes="人力资源完税-通过id查询")
	@GetMapping(value = "/queryById")
	public Result<?> queryById(@RequestParam(name="id",required=true) String id) {
		BuGsfwptRlzy buGsfwptRlzy = buGsfwptRlzyService.getById(id);
		if(buGsfwptRlzy==null) {
			return Result.error("未找到对应数据");
		}
		return Result.OK(buGsfwptRlzy);
	}

	@AutoLog(value = "人力资源完税-打印数据-获取页数")
	@ApiOperation(value="人力资源完税-打印数据-获取页数", notes="人力资源完税-打印数据-获取页数")
	@RequestMapping(value = "/customRlzyPrintCounts")
	public Result<?> customRlzyPrintCounts(BuGsfwptRlzy buGsfwptRlzy, HttpServletRequest request) {
		if(null == buGsfwptRlzy) buGsfwptRlzy = new BuGsfwptRlzy();
		// 税款日期，默认当前月
		if(null == buGsfwptRlzy.getSkrq()) {
			buGsfwptRlzy.setSkrq(new Date());
		}
		List<String> selectionList = new ArrayList<>() ;
		String selections = request.getParameter("selections");
		if (oConvertUtils.isNotEmpty(selections)) {
			selectionList = Arrays.asList(selections.split(","));
			buGsfwptRlzy.setIdList(selectionList);
		}
		List<QyNumVo> qyNumList = buGsfwptRlzyService.queryQyList(buGsfwptRlzy);

		if(CollectionUtil.isNotEmpty(qyNumList)) {
			/**
			 * 每次显示50页，每页30条，不足的按一页算
			 */
			int s = 30,
				p = 50,
				c = 0;
			for(QyNumVo qv : qyNumList){
				// 数据量
				int num = qv.getNum() ;
				c += (num - 1) / s + 1;
			}
			Integer num = Integer.valueOf((c - 1) / p + 1);
			return Result.OK(num);
		}
		return Result.OK(Integer.valueOf(0));
	}

	public List<QyNumVo> getQyList(List<QyNumVo> qyNumList, Integer pageNum) {
		int s = 30,
			p = 50,
			c = 0;
		List<QyNumVo> qyList = new ArrayList<>();
		for(QyNumVo qv : qyNumList){
			// 数据量
			int num = qv.getNum() ;
			int start = (pageNum - 1) * p + 1;
			int end = pageNum * p;

			int a = (num - 1) / s + 1; // 本企业总页数
			int t1 = 1, t2 = a;
			if(c >= end) {
				break;
			}
			// 上次打印内
			if(c + a < start) {
				c += a;
				continue;
			}

			if(c < start) {
				t1 = start - c;// 开始
				if(c + a <= end) {
					t2 = a;
				} else {
					t2 = t1 + p - 1;
				}
			} else {
				if(c + a <= end) {
					t2 = a;
				} else {
					t2 = t1 + end - c - 1;
				}
			}

			c += a;

			qv.setT1(t1);
			qv.setT2(t2);
			qyList.add(qv);
		}
		return qyList;
	}
	@SneakyThrows
	@AutoLog(value = "人力资源完税-打印数据列表")
	@ApiOperation(value="人力资源完税-打印数据列表", notes="人力资源完税-打印数据列表")
	@RequestMapping(value = "/customRlzyPrintList")
	public Result<?> customRlzyPrintList(BuGsfwptRlzy buGsfwptRlzy ,
											   Integer printPageNum,
											   HttpServletRequest request) {

		// 税款日期，默认当前月
		final Date lrrq = buGsfwptRlzy.getLrrq() != null ? buGsfwptRlzy.getLrrq() : new Date() ;
		if(null == buGsfwptRlzy.getSkrq()) {
			buGsfwptRlzy.setSkrq(new Date());
		}

		// 准备本次全量数据
		List<BuGsfwptRlzy> list = buGsfwptRlzyService.queryRlzyListByCustom(buGsfwptRlzy);
		Map<String, List<BuGsfwptRlzy>> mAll = new HashMap<>();
		for(BuGsfwptRlzy d : list) {
			String qymc = d.getQymc();
			if(!mAll.containsKey(qymc)) {
				List<BuGsfwptRlzy> v = new ArrayList<>();
				mAll.put(qymc, v);
			}
			mAll.get(qymc).add(d);
		}
		list = null;


		// 默认每页显示30 条数据
		int dataNum = 30 ;
		// Step.1 查询企业数量，根据企业数量创建sheet
		List<String> selectionList = new ArrayList<>() ;
		String selections = request.getParameter("selections");
		if (oConvertUtils.isNotEmpty(selections)) {
			selectionList = Arrays.asList(selections.split(","));
			buGsfwptRlzy.setIdList(selectionList);
		}
		List<QyNumVo> qyNumList = buGsfwptRlzyService.queryQyList(buGsfwptRlzy);
		// Step.2 存放企业名称，创建sheet页面
		List<String> qymcList = new ArrayList<>() ;
		// Step.3 多sheet处理

		// 存放sheet 数据
		List<List<Map<String, Object>>> sheetList = new CopyOnWriteArrayList() ;
		// 记录sheet数据list
		Map<String, Object> sheetMap = new ConcurrentHashMap();
		// 遍历请求数据，创建sheet 页面

		// 多线程处理
		int pageNum = null == printPageNum || 0 == printPageNum ? 1 : printPageNum;
		// 准备多线程处理的数据
		List<QyNumVo> qyList = getQyList(qyNumList, pageNum);
		// 每个线程处理5个企业
		int s = 5;
		int n = (qyList.size() - 1 ) / s + 1;
		CountDownLatch countDownLatch = new CountDownLatch( n );
		for(int i = 0; i < n; i++) {
			final int fromIndex = i * s ;
			final int toIndex = (i + 1) * s > qyList.size() ?  qyList.size() : (i + 1) * s ;
			Runnable runnable = new Runnable(){
				@Override
				public void run() {
					try {
						List<QyNumVo> subQyList = qyList.subList(fromIndex, toIndex);
						for(QyNumVo qv : subQyList){
							// 数据量
							int num = qv.getNum() ;
							// 存放数据map
							Map<String, Object> map = new HashMap<String, Object>();
							// 企业名称
							String qymc = qv.getQymc() ;

							// 服务厅
							String fwt = qv.getFwt() ;
							// 设置查询参数
							BuGsfwptRlzy bf = new BuGsfwptRlzy() ;
							BeanUtil.copyProperties(buGsfwptRlzy, bf);
							bf.setQymc(qymc) ;
							bf.setFwt(fwt) ;
							bf.setSkrq(buGsfwptRlzy.getSkrq()) ;
							IPage<BuGsfwptRlzy> pageList = null  ;
							// 查询数据 , 少于默认记录数，发一次请求；
							if(num <= dataNum ) {
//								Page<BuGsfwptRlzy> page = new Page<BuGsfwptRlzy>(1, num);
//								pageList = buGsfwptRlzyService.queryRlzyPageListByCustom(page, bf);
//								List<BuGsfwptRlzy> records = pageList.getRecords();
								List<BuGsfwptRlzy> records = mAll.get(qymc);
								List<BuGsfwptRlzy> exportList = null;
								List<String> selectionList = new ArrayList<>() ;
								// 过滤选中数据
//								String selections = request.getParameter("selections");
								if (oConvertUtils.isNotEmpty(selections)) {
									selectionList = Arrays.asList(selections.split(","));
									List<String> finalSelectionList = selectionList;
									exportList = records.stream().filter(item -> finalSelectionList.contains(item.getId())).collect(Collectors.toList());
								} else {
									exportList = records;
								}
								if(exportList.size() > 0){
									// 统计当前页数据总和，交税依据、实缴税额、代征税额
									TotalParamVo tv = new TotalParamVo() ;
									tv.setFwt(bf.getFwt());
									tv.setQymc(bf.getQymc());
									tv.setSkrq(bf.getSkrq());
									tv.setSize(0);
									tv.setTotal(dataNum);
									tv.setIdList(selectionList);
									QyNumVo q = buGsfwptRlzyService.queryRlzyTotalData(tv);
									// 添加录入日期
									exportList.get(0).setLrrq(lrrq) ;
									// 添加合计行
									BuGsfwptRlzy by = new BuGsfwptRlzy() ;
									by.setSkssq("合计") ;
									by.setJsyj(q.getJsyj()) ;
									by.setYdzse(q.getYdzse()) ;
									by.setSjse(q.getSjse()) ;
									exportList.add(by) ;
									// 添加数据到map
									map.put(NormalExcelConstants.DATA_LIST, exportList);//数据集合
									List<Map<String, Object>> listMap = new ArrayList<Map<String, Object>>();
									// 不包含企业名称，创建该企业的sheet
									if(!qymcList.contains(qymc)){
										qymcList.add(qymc);

										listMap.add(map);
										sheetMap.put(qymc,listMap) ;
										sheetList.add(listMap) ;
									}else {
										listMap = (List<Map<String, Object>>) sheetMap.get(qymc);
										listMap.add(map) ;
									}
								}

							}else  {
								List<BuGsfwptRlzy> allRecords = mAll.get(qymc);
								for (int i = qv.getT1(); i <= qv.getT2() ; i++) {
//									Page<BuGsfwptRlzy> page = new Page<BuGsfwptRlzy>(i, dataNum);
//									pageList = buGsfwptRlzyService.queryRlzyPageListByCustom(page, bf);
									// 存放数据列表
									map = new HashMap<String, Object>();
//									List<BuGsfwptRlzy> records = pageList.getRecords();

									int from = (i-1) * dataNum ;
									int to = i * dataNum > allRecords.size() ?  allRecords.size() : i * dataNum ;

									List<BuGsfwptRlzy> records = new ArrayList<>();
									for (int j = from; j < to; j++) {
										records.add(allRecords.get(j));
									}
									List<BuGsfwptRlzy> exportList = null;
									// 过滤选中数据
//									String selections = request.getParameter("selections");
									List<String> selectionList = new ArrayList<>() ;
									if (oConvertUtils.isNotEmpty(selections)) {
										selectionList = Arrays.asList(selections.split(","));
										List<String> finalSelectionList = selectionList;
										exportList = records.stream().filter(item -> finalSelectionList.contains(item.getId())).collect(Collectors.toList());
									} else {
										exportList = records;
									}
									if(exportList.size() > 0){
										// 统计当前页数据总和，交税依据、实缴税额、代征税额
										TotalParamVo tv = new TotalParamVo() ;
										tv.setFwt(bf.getFwt());
										tv.setQymc(bf.getQymc());
										tv.setSkrq(bf.getSkrq());
										tv.setSize((i-1) * dataNum);
										tv.setTotal(dataNum);
										tv.setIdList(selectionList);
										QyNumVo q = buGsfwptRlzyService.queryRlzyTotalData(tv);
										//map.put("title",exportParams);//表格Title
										// 添加录入日期
										exportList.get(0).setLrrq(lrrq) ;
										// 添加合计列
										BuGsfwptRlzy by = new BuGsfwptRlzy() ;
										by.setSkssq("合计") ;
										by.setJsyj(q.getJsyj()) ;
										by.setYdzse(q.getYdzse()) ;
										by.setSjse(q.getSjse()) ;
										exportList.add(by) ;
										map.put(NormalExcelConstants.DATA_LIST, exportList);//数据集合
										/*map.put("totalList", totalList);*///数据集合
										List<Map<String, Object>> listMap = new ArrayList<Map<String, Object>>();
										// 不包含企业名称，创建该企业的sheet
										if(!qymcList.contains(qymc)){
											qymcList.add(qymc);

											listMap.add(map);
											sheetMap.put(qymc,listMap) ;
											sheetList.add(listMap) ;
										}else {
											listMap = (List<Map<String, Object>>) sheetMap.get(qymc);
											listMap.add(map) ;
										}
									}
								}
							}
						}
					}  finally {
						countDownLatch.countDown();
					}
				}
			};
			executorService.execute(runnable);
		}
		countDownLatch.await();




//		for(QyNumVo qv : qyNumList){
//			// 数据量
//			int num = qv.getNum() ;
//			// 存放数据map
//			Map<String, Object> map = new HashMap<String, Object>();
//			// 企业名称
//			String qymc = qv.getQymc() ;
//
//			// 服务厅
//			String fwt = qv.getFwt() ;
//			// 设置查询参数
//			BuGsfwptRlzy bf = new BuGsfwptRlzy() ;
//			BeanUtil.copyProperties(buGsfwptRlzy, bf);
//			bf.setQymc(qymc) ;
//			bf.setFwt(fwt) ;
//			bf.setSkrq(buGsfwptRlzy.getSkrq()) ;
//			IPage<BuGsfwptRlzy> pageList = null  ;
//			// 查询数据 , 少于默认记录数，发一次请求；
//			if(num <= dataNum ) {
//				Page<BuGsfwptRlzy> page = new Page<BuGsfwptRlzy>(1, num);
//				pageList = buGsfwptRlzyService.queryRlzyPageListByCustom(page, bf);
//				List<BuGsfwptRlzy> records = pageList.getRecords();
//				List<BuGsfwptRlzy> exportList = null;
//				List<String> selectionList = new ArrayList<>() ;
//				// 过滤选中数据
//				String selections = request.getParameter("selections");
//				if (oConvertUtils.isNotEmpty(selections)) {
//					selectionList = Arrays.asList(selections.split(","));
//					List<String> finalSelectionList = selectionList;
//					exportList = records.stream().filter(item -> finalSelectionList.contains(this.getId(item))).collect(Collectors.toList());
//				} else {
//					exportList = records;
//				}
//				if(exportList.size() > 0){
//					// 统计当前页数据总和，交税依据、实缴税额、代征税额
//					TotalParamVo tv = new TotalParamVo() ;
//					tv.setFwt(bf.getFwt());
//					tv.setQymc(bf.getQymc());
//					tv.setSkrq(bf.getSkrq());
//					tv.setSize(0);
//					tv.setTotal(dataNum);
//					tv.setIdList(selectionList);
//					QyNumVo q = buGsfwptRlzyService.queryRlzyTotalData(tv);
//					// 添加录入日期
//					exportList.get(0).setLrrq(lrrq) ;
//					// 添加合计行
//					BuGsfwptRlzy by = new BuGsfwptRlzy() ;
//					by.setSkssq("合计") ;
//					by.setJsyj(q.getJsyj()) ;
//					by.setYdzse(q.getYdzse()) ;
//					by.setSjse(q.getSjse()) ;
//					exportList.add(by) ;
//					// 添加数据到map
//					map.put(NormalExcelConstants.DATA_LIST, exportList);//数据集合
//					List<Map<String, Object>> listMap = new ArrayList<Map<String, Object>>();
//					// 不包含企业名称，创建该企业的sheet
//					if(!qymcList.contains(qymc)){
//						qymcList.add(qymc);
//
//						listMap.add(map);
//						sheetMap.put(qymc,listMap) ;
//						sheetList.add(listMap) ;
//					}else {
//						listMap = (List<Map<String, Object>>) sheetMap.get(qymc);
//						listMap.add(map) ;
//					}
//				}
//
//			}else  {
//				for (int i = t1; i <= t2 ; i++) {
//					Page<BuGsfwptRlzy> page = new Page<BuGsfwptRlzy>(i, dataNum);
//					pageList = buGsfwptRlzyService.queryRlzyPageListByCustom(page, bf);
//
//
//					// 存放数据列表
//					map = new HashMap<String, Object>();
//					List<BuGsfwptRlzy> records = pageList.getRecords();
//					List<BuGsfwptRlzy> exportList = null;
//					// 过滤选中数据
//					String selections = request.getParameter("selections");
//					List<String> selectionList = new ArrayList<>() ;
//					if (oConvertUtils.isNotEmpty(selections)) {
//						selectionList = Arrays.asList(selections.split(","));
//						List<String> finalSelectionList = selectionList;
//						exportList = records.stream().filter(item -> finalSelectionList.contains(this.getId(item))).collect(Collectors.toList());
//					} else {
//						exportList = records;
//					}
//					if(exportList.size() > 0){
//						// 统计当前页数据总和，交税依据、实缴税额、代征税额
//						TotalParamVo tv = new TotalParamVo() ;
//						tv.setFwt(bf.getFwt());
//						tv.setQymc(bf.getQymc());
//						tv.setSkrq(bf.getSkrq());
//						tv.setSize((i-1) * dataNum);
//						tv.setTotal(dataNum);
//						tv.setIdList(selectionList);
//						QyNumVo q = buGsfwptRlzyService.queryRlzyTotalData(tv);
//						//map.put("title",exportParams);//表格Title
//						// 添加录入日期
//						exportList.get(0).setLrrq(lrrq) ;
//						// 添加合计列
//						BuGsfwptRlzy by = new BuGsfwptRlzy() ;
//						by.setSkssq("合计") ;
//						by.setJsyj(q.getJsyj()) ;
//						by.setYdzse(q.getYdzse()) ;
//						by.setSjse(q.getSjse()) ;
//						exportList.add(by) ;
//						map.put(NormalExcelConstants.DATA_LIST, exportList);//数据集合
//						/*map.put("totalList", totalList);*///数据集合
//						List<Map<String, Object>> listMap = new ArrayList<Map<String, Object>>();
//						// 不包含企业名称，创建该企业的sheet
//						if(!qymcList.contains(qymc)){
//							qymcList.add(qymc);
//
//							listMap.add(map);
//							sheetMap.put(qymc,listMap) ;
//							sheetList.add(listMap) ;
//						}else {
//							listMap = (List<Map<String, Object>>) sheetMap.get(qymc);
//							listMap.add(map) ;
//						}
//					}
//				}
//			}
//
//
//		}
		return Result.OK(sheetList );
	}
    /**
    * 导出excel
    *
    * @param request
    * @param buGsfwptRlzy
    */
    @RequestMapping(value = "/exportXls")
    public void exportXls(HttpServletRequest request, HttpServletResponse response, BuGsfwptRlzy buGsfwptRlzy) {
		String lrrq = DateUtils.date2Str(new Date() ,new SimpleDateFormat("yyyy-MM-dd")) ;
		if(buGsfwptRlzy.getLrrq() !=null){
			lrrq = DateUtils.date2Str(buGsfwptRlzy.getLrrq() ,new SimpleDateFormat("yyyy-MM-dd")) ;
		}
		// 默认当月
		if(buGsfwptRlzy.getSkrq() ==null){
			buGsfwptRlzy.setSkrq(new Date());
		}
		exportXlsSheet(request, response, buGsfwptRlzy,  "委托代征申报缴款查询"  ,lrrq);
    }

	/**
	 * 根据每页sheet数量导出多sheet
	 *
	 * @param request
	 * @param buGsfwptRlzy 实体类
	 * @param title 标题
	 * @param lrrq 录入日期，自定义
	 * @param request
	 */
	@SneakyThrows
	protected void exportXlsSheet(HttpServletRequest request, HttpServletResponse response, BuGsfwptRlzy buGsfwptRlzy, String title , String lrrq) {

		// 准备本次全量数据
		List<BuGsfwptRlzy> list = buGsfwptRlzyService.queryRlzyListByCustom(buGsfwptRlzy);
		Map<String, List<BuGsfwptRlzy>> mAll = new HashMap<>();
		for(BuGsfwptRlzy d : list) {
			String qymc = d.getQymc();
			if(!mAll.containsKey(qymc)) {
				List<BuGsfwptRlzy> v = new ArrayList<>();
				mAll.put(qymc, v);
			}
			mAll.get(qymc).add(d);
		}
		list = null;

		// 默认每页显示30 条数据
		int dataNum = 30 ;
		// Step.1 查询企业数量，根据企业数量创建sheet
		String selections = request.getParameter("selections");
		if (oConvertUtils.isNotEmpty(selections)) {
			List<String> selectionList = Arrays.asList(selections.split(","));
			buGsfwptRlzy.setIdList(selectionList);
		}

		List<QyNumVo> allQyNumList = buGsfwptRlzyService.queryQyList(buGsfwptRlzy);

		String dirName = UUID.randomUUID().toString();
		//创建临时目录
		File tempDir = new File(System.getProperty("java.io.tmpdir") + File.separator + dirName + File.separator );
		if (!tempDir.mkdir()) {
			throw new RuntimeException("Failed to create temporary directory: " + dirName);
		}

		// 每个excel 最多100个sheet
		int fileSheetNums = 100;
		int m = (allQyNumList.size() - 1 ) / fileSheetNums + 1;
		for(int q = 0; q < m; q++) {
			final int f = q * fileSheetNums ;
			final int t = (q + 1) * fileSheetNums > allQyNumList.size() ?  allQyNumList.size() : (q + 1) * fileSheetNums ;
			List<QyNumVo> qyNumList = allQyNumList.subList(f, t);

			// Step.2 存放企业名称，创建sheet页面
			List<String> qymcList = new ArrayList<>() ;
			// Step.3 多sheet处理

			// 存放sheet 数据
			List<List<Map<String, Object>>> sheetList = new CopyOnWriteArrayList<>() ;

			// 记录sheet数据list
			Map<String, Object> sheetMap = new ConcurrentHashMap<>();

			// 准备多线程处理的数据
			// 每个线程处理10个企业
			int s = 10;
			int n = (qyNumList.size() - 1 ) / s + 1;
			CountDownLatch countDownLatch = new CountDownLatch( n );
			for(int i = 0; i < n; i++) {
				final int fromIndex = i * s ;
				final int toIndex = (i + 1) * s > qyNumList.size() ?  qyNumList.size() : (i + 1) * s ;

				Runnable runnable = new Runnable(){
					@Override
					public void run() {
						try {
							List<QyNumVo> subQyList = qyNumList.subList(fromIndex, toIndex);
							// 遍历请求数据，创建sheet 页面
							for(QyNumVo qv : subQyList){
								// 存放统计数据list
								List<Double> totalList = new ArrayList<>() ;
								totalList.add(qv.getJsyj()) ;
								totalList.add(qv.getYdzse()) ;
								totalList.add(qv.getSjse()) ;
								// 存放数据map
								Map<String, Object> map = new HashMap<String, Object>();
								// 企业名称
								String qymc = qv.getQymc() ;
								// 数据量
								int num = qv.getNum() ;
								// 服务厅
								String fwt = qv.getFwt() ;
								// 设置查询参数
								BuGsfwptRlzy bf = new BuGsfwptRlzy() ;
								bf.setQymc(qymc) ;
								bf.setFwt(fwt) ;
								bf.setSkrq(buGsfwptRlzy.getSkrq()) ;
								IPage<BuGsfwptRlzy> pageList = null  ;
								// 查询数据 , 少于默认记录数，发一次请求；
								if(num <= dataNum ) {
//								Page<BuGsfwptRlzy> page = new Page<BuGsfwptRlzy>(1, num);
//								pageList = buGsfwptRlzyService.queryRlzyPageListByCustom(page, bf);
//								List<BuGsfwptRlzy> records = pageList.getRecords();
									List<BuGsfwptRlzy> records = mAll.get(qymc);
									List<BuGsfwptRlzy> exportList = null;
									// 过滤选中数据
//								String selections = request.getParameter("selections");
									if (oConvertUtils.isNotEmpty(selections)) {
										List<String> selectionList = Arrays.asList(selections.split(","));
										exportList = records.stream().filter(item -> selectionList.contains(item.getId())).collect(Collectors.toList());
									} else {
										exportList = records;
									}
									if(exportList.size() > 0){
										ExportParams  exportParams=new ExportParams(title , fwt +"," + qymc +"," + "录入日期：" + lrrq, qymc,upLoadPath);
										exportParams.setType(ExcelType.XSSF);
										//map.put("title",exportParams);//表格Title
										map.put(NormalExcelConstants.PARAMS,exportParams);//表格Title
										map.put(NormalExcelConstants.CLASS,BuGsfwptRlzy.class);//表格对应实体
										map.put(NormalExcelConstants.DATA_LIST, exportList);//数据集合
										map.put("totalList", totalList);//数据集合
										List<Map<String, Object>> listMap = new ArrayList<Map<String, Object>>();
										// 不包含企业名称，创建该企业的sheet
										if(!qymcList.contains(qymc)){
											qymcList.add(qymc);

											listMap.add(map);
											sheetMap.put(qymc,listMap) ;
											sheetList.add(listMap) ;
										}else {
											listMap = (List<Map<String, Object>>) sheetMap.get(qymc);
											listMap.add(map) ;
										}
									}

								}else  {
									List<BuGsfwptRlzy> allRecords = mAll.get(qymc);
									// 分页次数
									int count = (int)Math.ceil(Double.valueOf(num)/dataNum);
									for (int i = 1; i <=count ; i++) {
//									Page<BuGsfwptRlzy> page = new Page<BuGsfwptRlzy>(i, dataNum);
//									pageList = buGsfwptRlzyService.queryRlzyPageListByCustom(page, bf);
										map = new HashMap<String, Object>();
//									List<BuGsfwptRlzy> records = pageList.getRecords();

										int from = (i-1) * dataNum ;
										int to = i * dataNum > allRecords.size() ?  allRecords.size() : i * dataNum ;

										List<BuGsfwptRlzy> records = new ArrayList<>();
										for (int j = from; j < to; j++) {
											records.add(allRecords.get(j));
										}

										List<BuGsfwptRlzy> exportList = null;
										// 过滤选中数据
										String selections = request.getParameter("selections");
										if (oConvertUtils.isNotEmpty(selections)) {
											List<String> selectionList = Arrays.asList(selections.split(","));
											exportList = records.stream().filter(item -> selectionList.contains(item.getId())).collect(Collectors.toList());
										} else {
											exportList = records;
										}
										if(exportList.size() > 0){
											ExportParams  exportParams=new ExportParams(title , fwt +"," + qymc +"," + "录入日期：" + lrrq, qymc,upLoadPath);
											exportParams.setType(ExcelType.XSSF);
											//map.put("title",exportParams);//表格Title
											map.put(NormalExcelConstants.PARAMS,exportParams);//表格Title
											map.put(NormalExcelConstants.CLASS,BuGsfwptRlzy.class);//表格对应实体
											map.put(NormalExcelConstants.DATA_LIST, exportList);//数据集合
											map.put("totalList", totalList);//数据集合
											List<Map<String, Object>> listMap = new ArrayList<Map<String, Object>>();
											// 不包含企业名称，创建该企业的sheet
											if(!qymcList.contains(qymc)){
												qymcList.add(qymc);

												listMap.add(map);
												sheetMap.put(qymc,listMap) ;
												sheetList.add(listMap) ;
											}else {
												listMap = (List<Map<String, Object>>) sheetMap.get(qymc);
												listMap.add(map) ;
											}
										}

									}
								}


							}
						}  finally {
							countDownLatch.countDown();
						}
					}
				};
				executorService.submit(runnable);
			}
			countDownLatch.await();
			// 生成数据文件
			Path path = Paths.get(tempDir.getPath(), "人力资源完税"+(q+1)+".xls");
			FileOutputStream outputStream = null;
			Workbook workbook = null;
			try {
				outputStream = new FileOutputStream(path.toFile());
				workbook = generateWorkbook(sheetList);
				workbook.write(outputStream);
			} finally {
				if(null != outputStream)
					outputStream.close();
				if(null != workbook)
					workbook.close();
			}


		}
		String zipDirUUID = UUID.randomUUID().toString();
		File zipDir = new File(System.getProperty("java.io.tmpdir") + File.separator + zipDirUUID + File.separator);
		//创建临时目录
		if (!zipDir.mkdir()) {
			throw new RuntimeException("Failed to create temporary directory: " + zipDir);
		}
		Path zipPath = null;
		try{
			// 压缩到的位置
			zipPath = Paths.get(zipDir.getPath(), "人力资源完税.zip");
			// 压缩文件
			ZipUtil.zip(zipPath.toFile(), false, tempDir.listFiles());
			downloadZip(response,  zipPath.toFile());
			// TODO
		} finally {
			// 删除临时目录及其内容
			deleteDirectory(tempDir);
			deleteDirectory(zipDir);
		}


		// Step.4 AutoPoi 导出Excel
//		ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
////		mv.addObject(NormalExcelConstants.FILE_NAME, title); //此处设置的filename无效 ,前端会重更新设置一下
////		mv.addObject(NormalExcelConstants.MAP_LIST, sheetList);
//		mv.addObject("filePath", zipPath);
//		return mv;
	}

	/**
	 * 下载ZIP压缩包(会对下载后的压缩包进行删除)
	 *
	 * @param file     zip压缩包文件
	 * @param response 响应
	 */
	public static void downloadZip(HttpServletResponse response, File file) throws Exception {
		FileInputStream inStream = null;
		ServletOutputStream os = null;
		try {
			//设置下载zip的头信息
			// 对文件名重新编码
//			zipName = new String(zipName.getBytes("UTF-8"), "ISO-8859-1");
			response.setCharacterEncoding("UTF-8");
			response.setContentType("application/octet-stream");
			response.setHeader("Content-Disposition", "attachment; filename=" + file.getName());

			os = response.getOutputStream();

			inStream = new FileInputStream(file);
			byte[] buf = new byte[4096];
			int readLength;
			while (((readLength = inStream.read(buf)) != -1)) {
				os.write(buf, 0, readLength);
			}
			os.flush();
		} finally {
			if (inStream != null) {
				inStream.close();
			}
			if (os != null) {
				try {
					os.close();
				} catch (IOException e) {
					log.error("zip包下载关流失败:", e);
				}
			}
		}
	}

	private  void deleteDirectory(File dir) {
		if (dir.isDirectory()) {
			for (File file : dir.listFiles()) {
				deleteDirectory(file);
			}
		}
		dir.delete();
	}
	public Workbook generateWorkbook(List<List<Map<String, Object>>> sheetList) {
		Workbook workbook = new SXSSFWorkbook();
		String[] exportFields = null;

		List<List<Map<String, Object>>> list = sheetList;
		if (list.size() == 0 || list.get(0).size() == 0) {
			throw new RuntimeException("MAP_LIST IS NULL");
		}
		// workbook = ExcelExportUtil.exportSheetListExcel(list, exportFields);
		for(int i = 0; i < list.size(); ++i) {
			(new ExcelExportServer()).createSheetList(workbook, list.get(i) , exportFields);
		}

		return workbook;
	}
	/*protected ModelAndView exportXlsSheet(HttpServletRequest request, BuGsfwptRlzy buGsfwptRlzy,  String title , String lrrq) {
		// 默认每页显示30 条数据
		int dataNum = 30 ;
		// Step.1 查询企业数量，根据企业数量创建sheet
		List<QyNumVo> qyNumList = buGsfwptRlzyService.queryQyList(buGsfwptRlzy);
		// Step.2 存放企业名称，创建sheet页面
		List<String> qymcList = new ArrayList<>() ;
		// Step.3 多sheet处理
		List<Map<String, Object>> listMap = new ArrayList<Map<String, Object>>();
		Map<String, Object> sheetMap = new HashMap<String, Object>();
		// 遍历请求数据，创建sheet 页面
		for(QyNumVo qv : qyNumList){
			// 企业名称
			String qymc = qv.getQymc() ;
			// 数据量
			int num = qv.getNum() ;
			// 服务厅
			String fwt = qv.getFwt() ;
			// 设置查询参数
			BuGsfwptRlzy bf = new BuGsfwptRlzy() ;
			bf.setQymc(qymc) ;
			bf.setFwt(fwt) ;
			bf.setSkrq(buGsfwptRlzy.getSkrq()) ;
			IPage<BuGsfwptRlzy> pageList = null  ;
			// 查询数据 , 少于默认记录数，发一次请求；
			if(num <= dataNum) {
				Page<BuGsfwptRlzy> page = new Page<BuGsfwptRlzy>(1, num);
				pageList = buGsfwptRlzyService.queryRlzyPageListByCustom(page, bf);
			}else {
				// 分页次数
				int count = (int)Math.ceil(num/dataNum);
				for (int i = 1; i <=count ; i++) {
					Page<BuGsfwptRlzy> page = new Page<BuGsfwptRlzy>(i, dataNum);
					pageList = buGsfwptRlzyService.queryRlzyPageListByCustom(page, bf);
				}
			}
			List<BuGsfwptRlzy> records = pageList.getRecords();
			List<BuGsfwptRlzy> exportList = null;
			// 过滤选中数据
			String selections = request.getParameter("selections");
			if (oConvertUtils.isNotEmpty(selections)) {
				List<String> selectionList = Arrays.asList(selections.split(","));
				exportList = records.stream().filter(item -> selectionList.contains(this.getId(item))).collect(Collectors.toList());
			} else {
				exportList = records;
			}
			Map<String, Object> map = new HashMap<String, Object>();
			// 不包含企业名称，创建该企业的sheet
			if(!qymcList.contains(qymc)){
				qymcList.add(qymc);
				sheetMap.put(qymc,map) ;
			}else {
				map = (Map<String, Object>) sheetMap.get(qymc);
			}

			ExportParams  exportParams=new ExportParams(title , fwt +"	" + qymc +" 	" + " 录入日期：" + lrrq, qymc,upLoadPath);
			exportParams.setType(ExcelType.XSSF);
			//map.put("title",exportParams);//表格Title
			map.put(NormalExcelConstants.PARAMS,exportParams);//表格Title
			map.put(NormalExcelConstants.CLASS,BuGsfwptRlzy.class);//表格对应实体
			map.put(NormalExcelConstants.DATA_LIST, exportList);//数据集合
			listMap.add(map);
		}

		// Step.4 AutoPoi 导出Excel
		ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
		mv.addObject(NormalExcelConstants.FILE_NAME, title); //此处设置的filename无效 ,前端会重更新设置一下
		mv.addObject(NormalExcelConstants.MAP_LIST, listMap);
		return mv;
	}*/
	/**
	 * 获取对象ID
	 *
	 * @return
	 */
	private String getId(Object item) {
		try {
			return PropertyUtils.getProperty(item, "id").toString();
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
    /**
      * 通过excel导入数据
    *
    * @param request
    * @param response
    * @return
    */
    @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
    public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
        return super.importExcel(request, response, BuGsfwptRlzy.class);
    }
	@RequestMapping(value = "/getDlmc")
    public Result<?> getDlmc(HttpServletRequest request, HttpServletResponse response ,String dzzt) {
		if(StringUtils.isNotBlank(dzzt)){
			List<DictVo> pageList = buGsfwptRlzyService.queryDictByDzzt(dzzt);
			return Result.OK(pageList);
		}else {
			return Result.error("参数为空");
		}
    }
	@RequestMapping(value = "/getQymc")
	public Result<?> getQymc(HttpServletRequest request, HttpServletResponse response ,String dlmc , String dzzt) {
		if(StringUtils.isNotBlank(dlmc) && StringUtils.isNotBlank(dzzt)){
			List<DictVo> pageList = buGsfwptRlzyService.queryDictByDlmc(dlmc ,dzzt);
			return Result.OK(pageList);
		}else {
			return Result.error("参数为空");
		}
	}
}
